UI
pubspec.yaml
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
flutter_svg: ^2.0.10+1
line_icons: ^2.0.3
main.dart
import 'package:flutter/material.dart';
import 'package:online_cource_app/Home/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
constants.dart
import 'package:flutter/material.dart';
const primary = Color(0xFF6E8AFA);
const grey = Color(0xFFF5F5F7);
const bgColor = Color(0xFFE5E5E5);
const yellow = Color(0xFFFFD073);
const green = Color(0xFF49CC96);
const redLight = Color(0xFFFFEDEE);
Model/model.dart
const List onlineCourceOne = [
{
"id": "1",
"price":"\$50",
"title" : "Marketing",
"courses" : "17 Courses",
"img" : "images/marketing.png",
"img_detail" : "images/marketing_detail.png"
},
{
"id": "2",
"price": "\$90",
"title" : "Photography",
"courses" : "13 Courses",
"img" : "images/photography.png",
"img_detail" : "images/photography_detail.png"
},
{
"id": "3",
"price":"\$90",
"title" : "Music",
"courses" : "19 Courses",
"img" : "images/music.png",
"img_detail" : "images/music.png"
},
];
const List onlineCourceTwo = [
{
"id": "3",
"price": "\$50",
"title" : "UX Design",
"courses" : "25 Courses",
"img" : "images/ux.png",
"img_detail" : "images/ux_detail.png"
},
{
"id": "4",
"price": "\$80",
"title" : "Business",
"courses" : "20 Courses",
"img" : "images/business.png",
"img_detail" : "images/business_detail.png"
}
];
const List course_content = [
{
"id" : "01",
"duration" : "5:35 mins",
"title" : "Welcome to the Course",
"isWatched" : true
},
{
"id" : "02",
"duration" : "19:04 mins",
"title" : "Design Thinking - Intro",
"isWatched" : true
},
{
"id" : "03",
"duration" : "12:48 mins",
"title" : "Design Thinking Process",
"isWatched" : false
},
{
"id" : "04",
"duration" : "37:54 mins",
"title" : "Customer Perspective",
"isWatched" : false
}
];
Home/home_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:online_cource_app/Detail/course_detail.dart';
import 'package:online_cource_app/Model/model.dart.dart';
import 'package:online_cource_app/constants.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: myAppBar(),
body: ListView(
padding:
const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
children: [
const Text(
"Hey Alex,",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
const SizedBox(height: 15),
const Text(
"Find a course you want to learn",
style: TextStyle(
fontSize: 20,
),
),
const SizedBox(height: 30),
// for search bar
searchBar(),
const SizedBox(height: 35),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Categories",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
Text(
"See All",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 19,
color: primary,
),
),
],
),
const SizedBox(height: 35),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: onlineCourceOne.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoursesDetail(
imgDetail: onlineCourceOne[index]['img_detail'],
title: onlineCourceOne[index]['title'],
price: onlineCourceOne[index]['price'],
),
),
);
},
child: availableCourses(context, index),
);
}),
),
const SizedBox(
width: 20,
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: onlineCourceTwo.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CoursesDetail(
imgDetail: onlineCourceTwo[index]['img_detail'],
title: onlineCourceTwo[index]['title'],
price: onlineCourceTwo[index]['price'],
),
),
);
},
child: availableCoursesTwo(context, index),
);
}),
)
],
),
],
),
);
}
Padding availableCourses(BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width - 60 / 2,
height: 220,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
onlineCourceOne[index]['img'],
),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(20),
),
),
Padding(
padding: const EdgeInsets.only(top: 25, right: 18, left: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
onlineCourceOne[index]['title'],
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 8,
),
Text(
onlineCourceOne[index]['courses'],
style: TextStyle(
fontSize: 14, color: Colors.black.withOpacity(0.6)),
),
],
),
),
],
),
);
}
Padding availableCoursesTwo(BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Stack(
children: [
Container(
width: MediaQuery.of(context).size.width - 60 / 2,
height: 250,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
onlineCourceTwo[index]['img'],
),
fit: BoxFit.cover),
borderRadius: BorderRadius.circular(20),
),
),
Padding(
padding: const EdgeInsets.only(top: 25, right: 18, left: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
onlineCourceTwo[index]['title'],
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 8,
),
Text(
onlineCourceTwo[index]['courses'],
style: TextStyle(
fontSize: 14, color: Colors.black.withOpacity(0.6)),
),
],
),
),
],
),
);
}
Container searchBar() {
return Container(
height: 60,
decoration: BoxDecoration(
color: grey,
borderRadius: BorderRadius.circular(30),
),
child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 5),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Search for anything",
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.25),
),
prefixIcon: const Icon(
Icons.search,
color: Colors.black54,
)),
),
),
),
);
}
AppBar myAppBar() {
return AppBar(
backgroundColor: Colors.white,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
"images/burger_icon.svg",
),
Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(
"https://www.simplilearn.com/ice9/free_resources_article_thumb/how_to_become_A_programmer.jpg",
),
fit: BoxFit.cover),
),
),
],
),
);
}
}
Detail/course_content
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:online_cource_app/Model/model.dart.dart';
import 'package:online_cource_app/constants.dart';
class CourseContent extends StatelessWidget {
const CourseContent({
super.key,
required this.size,
});
final Size size;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: size.height * 0.4),
height: size.height * 0.55,
width: size.width,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
),
),
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 35),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Course Content",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
const SizedBox(
height: 25,
),
Column(
children: List.generate(course_content.length, (index) {
return Padding(
padding: const EdgeInsets.only(bottom: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
course_content[index]['id'],
style: TextStyle(
fontSize: 28,
color: Colors.black.withOpacity(0.3),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
course_content[index]['duration'],
style: TextStyle(
fontSize: 16,
color: Colors.black.withOpacity(0.5),
),
),
const SizedBox(
height: 5,
),
Text(
course_content[index]['title'],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
],
),
Container(
width: 45,
height: 45,
decoration: BoxDecoration(
color: course_content[index]["isWatched"]
? green
: green.withOpacity(0.4),
shape: BoxShape.circle,
),
child: Center(
child: SvgPicture.asset(
"images/play_icon.svg",
),
),
),
],
),
);
}),
)
],
),
),
);
}
}
Detail/course_detail
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:online_cource_app/Detail/course_content.dart';
import 'package:online_cource_app/constants.dart';
class CoursesDetail extends StatefulWidget {
final String imgDetail;
final String title;
final String price;
const CoursesDetail({
super.key,
required this.imgDetail,
required this.title,
required this.price,
});
@override
State createState() => _CoursesDetailState();
}
class _CoursesDetailState extends State {
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: [
Positioned.fill(
bottom: 350,
child: Container(
height: size.height * 0.45,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(widget.imgDetail),
fit: BoxFit.fill),
),
)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios,
),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_vert),
)
],
),
),
// for best seller
Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: const BoxDecoration(
color: yellow,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Text("BESTSELLER"),
),
),
const SizedBox(
height: 15,
),
// for title
Text(
widget.title,
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 15,
),
// for rating and no of user
Row(
children: [
Row(
children: [
SvgPicture.asset(
"images/user_icon.svg",
),
const SizedBox(
width: 5,
),
const Padding(
padding: EdgeInsets.only(top: 3),
child: Text(
"18k",
),
),
],
),
const SizedBox(
width: 25,
),
Row(
children: [
SvgPicture.asset(
"images/star_icon.svg",
),
const SizedBox(
width: 5,
),
const Padding(
padding: EdgeInsets.only(top: 3),
child: Text(
"4.8",
),
),
],
),
],
),
const SizedBox(
height: 25,
),
Row(
children: [
Text(
widget.price,
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
width: 15,
),
const Text(
"\$70",
style: TextStyle(
fontSize: 18,
decoration: TextDecoration.lineThrough,
),
),
],
)
],
),
),
],
),
CourseContent(size: size)
],
)
],
),
),
bottomSheet: bottomParts(),
);
}
Container bottomParts() {
var size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: Colors.white,
boxShadow: [
BoxShadow(
spreadRadius: 5,
blurRadius: 10,
color: Colors.black.withOpacity(0.05),
),
]),
child: Padding(
padding:
const EdgeInsets.only(left: 20, right: 20, top: 10, bottom: 15),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
height: 55,
width: 70,
decoration: BoxDecoration(
color: redLight,
borderRadius: BorderRadius.circular(30),
),
child: SvgPicture.asset("images/cart_icon.svg"),
),
const SizedBox(
width: 20,
),
Expanded(
child: Container(
padding: const EdgeInsets.all(10),
height: 65,
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(50),
),
child: const Center(
child: Text(
"BUY NOW",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold, fontSize: 15),
),
),
),
),
],
),
),
);
}
}